package org.jsonstruts.filter;

import java.io.File;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsonstruts.annotation.WebUrl;

public final class Dispatcher {

	private final String ExCEPTION_PACKAGE = "org\\jsonstruts";
	private static Dispatcher dispatcher = new Dispatcher();

	private Dispatcher() {
	};

	public static Dispatcher getDispatcher() {
		if (dispatcher == null)
			dispatcher = new Dispatcher();
		return dispatcher;
	}

	Log logger = LogFactory.getLog(Dispatcher.class);

	private String getPath() {
		String path = null;
		try {
			path = Dispatcher.class.getClassLoader().getResource("/").toURI().getPath();
			path = path.substring(1);
		} catch (URISyntaxException e) {
			logger.error(e);
		}

		return path;
	}

	public Set<String> getReflect() {
		return getClassName(getPath(), null);
	}

	Set<String> myClassName = new LinkedHashSet<String>();

	private Set<String> getClassName(String filePath, Set<String> className) {
		File file = new File(filePath);
		File[] childFiles = file.listFiles();
		for (File childFile : childFiles) {

			if (childFile.isDirectory()) {
				if (exceptpackager(childFile)) {
					myClassName.addAll(getClassName(childFile.getPath(), myClassName));
				}
			} else {
				String childFilePath = childFile.getPath();
				if (childFilePath.endsWith(".class")) {
					String childFil = childFilePath.substring(childFilePath.indexOf("\\classes") + 9, childFilePath.lastIndexOf("."));
					String child = childFil.replace("\\", ".");
					myClassName.add(child);
				}

			}
		}

		return myClassName;
	}

	private boolean exceptpackager(File childFile) {
		String path = childFile.getAbsolutePath();
		boolean isexcept = true;
		if (path.endsWith(ExCEPTION_PACKAGE))
			isexcept = false;
		return isexcept;
	}

	@SuppressWarnings("unchecked")
	public Map<String, String> InitMappingList() {
		Set<String> list = getReflect();
		Map<String, String> mapping = new HashMap<String, String>(list.size());
		for (String str : list) {
			Class classz = null;
			try {
				classz = Class.forName(str);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			WebUrl annotation = (WebUrl) classz.getAnnotation(WebUrl.class);
			if (annotation != null) {
				logger.info("Mapping url '" + annotation.value() + "' to handle '" + str + "'");
				mapping.put(annotation.value(), str);
			}
		}
		list = null;
		return mapping;
	}

}
